<!-- geomap的form配置比较特殊，依据glyph来进行，单独写个组件   -->
<template>
  <div class="geomap-form">
    <!-- <a-form
      :form="form"
      :label-col="{ span: labelCol }"
      :wrapper-col="{ span: wrapperCol }"
    >
      <a-form-item
        v-for="(item, i) in glyphConfig"
        :key="`form-item-${i}`"
        :label="item.label"
        :layout="item.layout"
        :class="item.layout"
      >
        <component
          :is="getCompType(item)"
          v-decorator="getDecorator(item)"
          v-bind="{ ...item.props, ...commonFormProps }"
          :props="item.props"
        >
        </component>
      </a-form-item>
    </a-form> -->
  </div>
</template>

<script lang="ts">
import { isEqual } from 'lodash'
import { Vue, Prop, Watch, Component } from 'vue-property-decorator'
import glyphProtoConfig from '@/components/common/VisualizationComp/geomap-glyph-proto-config'
import { IKeyValue, dynamicCompMaps, dynamicComponent } from './util'

@Component({
  components: {
    ...dynamicComponent,
  },
})
export default class GeomapForm extends Vue {
  @Prop({ default: () => ({}) }) formData!: IKeyValue // 渲染的表单值
  @Prop({
    type: Number,
    required: false,
    default() {
      return 10
    },
  })
  labelCol!: number

  @Prop({
    type: Number,
    required: false,
    default() {
      return 14
    },
  })
  wrapperCol!: number

  private form: any
  private commonFormProps = {
    size: 'small',
  }

  private glyphConfigFuncMapping: { [key: string]: any } = {
    point: this.getPointGlyphConfig,
    link: this.getLinkGlyphConfig,
    text: this.getPointGlyphConfig,
    world: () => glyphProtoConfig.world,
    'country-province': () => glyphProtoConfig.world,
    'country-city': () => glyphProtoConfig.world,
    'multi-subchart': () => glyphProtoConfig['multi-subchart'],
  }

  private get glyphType() {
    // glyph 类型
    const {
      geoLayer,
    }: // encodingType,
    { geoLayer: string[]; encodingType: string } =
      this.formData.glyphConfig || this.formData // ||后面是兼容老数据
    return geoLayer
  }

  private get glyphConfig() {
    if (!this.glyphType) {
      return []
    }
    let glyphConfig: IKeyValue[] = []
    const glyph = [
      'point',
      'link',
      'text',
      'world',
      'country-province',
      'country-city',
      'multi-subchart',
    ]
    glyph.forEach((key) => {
      if (this.glyphType.includes(key) && this.glyphConfigFuncMapping[key]) {
        glyphConfig = glyphConfig.concat(this.glyphConfigFuncMapping[key]())
      }
    })

    return glyphConfig
  }

  beforeCreate() {
    this.form = this.$form.createForm(this, {
      name: 'geomapForm',
      // @ts-ignore
      onValuesChange: (formEle, changedValues, allValues) => {
        // eslint-disable-next-line prefer-rest-params
        if (!isEqual(changedValues, allValues)) {
          // 因为formData变化后会setFieldsValue一次，也会触发 valuesChange，所以对比是否一致
          this.onFormValueChange(allValues)
        }
      },
    })
  }

  @Watch('formData', { immediate: true, deep: true })
  private onFormDataChange(newValue: IKeyValue, oldValue: IKeyValue) {
    if (!isEqual(newValue, oldValue)) {
      this.setFormData()
    }
  }

  /**
   * 设置表单 form 的值
   */
  private setFormData() {
    const {
      form: { getFieldsValue, setFieldsValue, resetFields },
      formData,
    } = this
    const geoFormData = {
      // 打平结构，方便处理
      ...formData,
      ...formData.glyphConfig,
    }
    this.$nextTick(() => {
      const values = getFieldsValue()
      const formDataKeysSet = new Set(Object.keys(geoFormData))
      // 设置值时只能设定表单中有的字段
      Object.keys(values).forEach((k) => {
        if (formDataKeysSet.has(k)) {
          // formData 中有对应的key才进行赋值
          values[k] = geoFormData[k]

          if (k === 'legendPosition') {
            values.legendPosition = values.legendPosition || 'null'
          }
        }
      })
      resetFields()
      setFieldsValue(values)
    })
  }

  private getPointGlyphConfig() {
    const { valueKey: encodingValue = [] } = this.formData
    return glyphProtoConfig.point(encodingValue.length > 0) // 有参与编码的值
  }

  private getLinkGlyphConfig() {
    const { valueKey: encodingValue = [] } = this.formData
    console.log(encodingValue)
    return glyphProtoConfig.link(encodingValue.length > 0)
    // return glyphProtoConfig.line(encodingValue.length > 0) // 有参与编码的值
  }

  /**
   * 根据配置获取渲染的组件类型
   */
  private getCompType(item: IKeyValue): string {
    const result = 'a-input'
    if (dynamicCompMaps[item.type]) {
      return dynamicCompMaps[item.type].component
    }
    return result
  }

  /**
   * 获取组件formItem 的 decorator
   * 必须，否则无法注册到form上
   */
  private getDecorator(field: IKeyValue) {
    const options: IKeyValue = { initialValue: field.defaultValue }
    if (field.type === 'switch') {
      options.valuePropName = 'checked'
    }
    return [field.name, options]
  }

  /**
   * formItem 数值变化
   */
  private onFormValueChange(allValues: any) {
    this.form.validateFields((error: any) => {
      if (!error) {
        // this.$emit('change', values)
        this.$emit('change', allValues) // onValuesChange 方法回调时只能用回调的参数，getFieldsValue等方法会有延迟，未生效
      }
    })
  }
}
</script>
